package com.fc.remoting.codec;

import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fc.remoting.exception.HeaderCheckFailedException;
import com.fc.remoting.message.RemotingMessage;
import com.fc.remoting.util.ChannelUtil;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

public class RemotingMessageDecoder extends LengthFieldBasedFrameDecoder {
	private static final Logger log = LoggerFactory.getLogger(RemotingMessageDecoder.class);

	private static final int DEFAULT_MAX_LENGTH = Short.MAX_VALUE;

	public RemotingMessageDecoder() {
		super(DEFAULT_MAX_LENGTH, 2, 2, 0, 4);
	}

	@Override
	protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
		ByteBuf frame = null;
		try {
			frame = (ByteBuf) super.decode(ctx, in);
			if (null == frame) {
				return null;
			}
			ByteBuffer byteBuffer = frame.nioBuffer();
			return RemotingMessage.createMessage(byteBuffer);
		}catch(HeaderCheckFailedException e){ 
			log.error(e.getMessage(), e);
			ChannelUtil.closeChannel(ctx.channel());
		}catch (Exception e) {
			log.error("decode exception, " + ChannelUtil.parseChannelRemoteAddr(ctx.channel()), e);
			ChannelUtil.closeChannel(ctx.channel());
		} finally {
			if (null != frame) {
				frame.release();
			}
		}
		return null;
	}
}
